// <copyright file="ObjectLayer.js" company="GameViewStudios">
// Copyright (c) 2010, 2011 All Right Reserved, http://www.gameviewstudios.com/
// </copyright>
//<added in version>1.0</added in version>
// <author>xyz</author>
// <email>xyz@xyz.org</email>
// <created date>2008-06-10</created date>
// <summary>Contains a ObjectLayer class which shows is responsible for handling touches and object placement</summary>

exports.GAObjectLayer = GAIsometricView.subclass({
    classname : 'GAObjectLayer',
    _currentSelectedObject: null,
    _differenceBetweenTouch: null,
    _actionType: null,
    _highLightedObject: null,
    _tempPositionSelected: null,
	_collisionObject: null,
	_shouldMove: null,
	_olDidMove: null,
	_shouldProposeMultipleObjects: null,
	_isMovingAlreadyPlacedObject: null,
	
	_isMultiMoveToolEnabled: null,
	_isMultiSellToolEnabled: null,
	_isRoadToolEnabled: null,
	_tutorial:null,
	_previouslyPlacedObjectPosition: null,
    _previousRoadPosition: null,
	_previousPreviousRoadPosition: null,
    
    initialize: function(){
    	//console.log("Log: GAObjectLayer")
    	this._differenceBetweenTouch = new Core.Vector(0,0);
		this._actionType = ActionType.ActionArrow;
		this._shouldProposeMultipleObjects = false;
		
		this._isMultiMoveToolEnabled = false;
		this._isMultiSellToolEnabled = false;
		this._isRoadToolEnabled = false;
        this._count = 0;
		this._myTouches = 0;										 
	},
    
    getHighLightedObject: function(){
    	return this._highLightedObject;
    },
    
    getMultiToolStatus: function(){
    	return (this._isMultiMoveToolEnabled || this._isMultiSellToolEnabled);
    },
    
    setPreviouslyPlacedObjectPosition: function(thePosition){
    	this._previouslyPlacedObjectPosition = thePosition;
    },
    
    getPreviouslyPlacedObjectPosition: function(){
    	return this._previouslyPlacedObjectPosition;
    },
    
    setPreviousRoadPosition: function(thePosition){
    	this._previousRoadPosition = thePosition;
    },
    
    getPreviousRoadPosition: function(){
    	return this._previousRoadPosition;
    },
    
    setPreviousPreviousRoadPosition: function(thePosition){
    	this._previousPreviousRoadPosition = thePosition;
    },
    
    getPreviousPreviousRoadPosition: function(){
    	return this._previousPreviousRoadPosition;
    },
    
    setIsMultiMoveToolEnabled: function(theState){
    	this._isMultiMoveToolEnabled = theState;
    },
    
    getIsMultiMoveToolEnabled: function(){
    	return this._isMultiMoveToolEnabled;
    },
    
    cancelMultiMove: function(){
    	if (this._highLightedObject){
    		this.cancelPlacingOfObject(this._highLightedObject);
    	}
    },
    
    setIsMultiSellToolEnabled: function(theState){
    	this._isMultiSellToolEnabled = theState;
    },
    
    getIsMultiSellToolEnabled: function(){
    	return this._isMultiSellToolEnabled;
    },
    
    cancelMultiSell: function(){
    	if ((this._highLightedObject) && (this._highLightedObject.objectState() != ObjectState.ObjectPlacement)){
    		this._highLightedObject.setOpacityToFull();
    		this._highLightedObject = null;
    	}
    },
    
    setIsRoadToolEnabled: function(theState){
    	this._isRoadToolEnabled = theState;
    },
    
    getIsRoadToolEnabled: function(){
    	return this._isRoadToolEnabled;
    },
    
    cancelRoadTool: function(){
    	console.log('Logger: Cancelling road tool');
    },
    
    setIsMovingAlreadyPlacedObject: function(theState){
    	this._isMovingAlreadyPlacedObject = theState;
    },
    
    getIsMovingAlreadyPlacedObject: function(){
    	return this._isMovingAlreadyPlacedObject;
    },
    
    setShouldProposeObjects: function(theState){
    	this._shouldProposeMultipleObjects = theState;
    },
    
    setCurrentSelectedObject: function(theObject){
    	this._currentSelectedObject = theObject;
    },
    
    setHighlightedObject: function(theObject){
    	this._highLightedObject = theObject;
    },
    
    getGridObjects: function(){
    	return this._gridObjects;
    },
    
    checkGridOnPositionIsEmpty: function(gridPosX, gridPosY, sizeX, sizeY){
    	var isEmpty = true;
    	for (var i = gridPosX; ((i < gridPosX + (4 * sizeX)) && (i < GAIsoMetricConfigurations.getGridSize().getX())); i = i + 4){
    		for (var j = gridPosY; ((j < gridPosY + (4 *sizeY)) && (j < GAIsoMetricConfigurations.getGridSize().getY())); j = j + 4){
	    		if (this._gridObjects[i][j] != null){
	    			return false;
	    		}
    		}
    	}
    	return isEmpty;
    },
    
    findPositionOnGrid: function(objSizeX, objSizeY, startX, startY){
    	var placeCoordinates = null;
		var placeFound = false;
		
		for (var i = startX; i <= GAIsoMetricConfigurations.getGridSize().getX() - (4 * objSizeX); i = i + 4){
    		for (var j = startY; j <= GAIsoMetricConfigurations.getGridSize().getY() - (4 * objSizeY); j = j + 4){
    			if (this.checkGridOnPositionIsEmpty(i, j, objSizeX, objSizeY)){
					placeFound = true;
					placeCoordinates = new Core.Vector(i, j);
					break;
    			}
    		}
    		if (placeFound){
    			break;
    		}
    	}
    	if (!placeFound){
    		placeCoordinates = new Core.Vector(-1, -1)
    	}
    	
    	return placeCoordinates;
    },
//		PLEASE DONT REMOVE THIS COMMENTED FUNCTION    
//
//
//    getZ: function(forObject, gridPosition){
//    	var constFix = 200;
//    	
//    	var gridSizeX = forObject.getGridSize().getX();
//    	var gridSizeY = forObject.getGridSize().getY();
//    	
//		var gridPositionX = gridPosition.getX();
//		var gridPositionY = gridPosition.getY() + gridSizeY;
//		
//		var calculatedZ = (GAIsoMetricConfigurations.getGridSize().getX() * 2 + 1) - (gridPositionX + gridPositionY + 1);
//		
//		calculatedZ = calculatedZ * 16;
//		
//		var zOrderOfbottomNeighborPoint = calculatedZ;
//		var previousFoundZOrder = - 1;
//		
//		if (gridSizeX > gridSizeY){
//			for (var neighborXStart = gridPositionX+1; neighborXStart < gridPositionX + gridSizeX; neighborXStart++){
//				var bottomNeighborPoint = new Core.Vector(neighborXStart, gridPositionY - 4)
//				if(bottomNeighborPoint.getY() > gridSizeY || bottomNeighborPoint.getX() > gridSizeX){
//					return calculatedZ + constFix;
//				}
//				var bottomNeighbor = this.objectForGridPosition(bottomNeighborPoint);
//				
//				if (bottomNeighbor){	
//					previousFoundZOrder = zOrderOfbottomNeighborPoint;
//					zOrderOfbottomNeighborPoint = bottomNeighbor.getObject().getDepth();
//					if (previousFoundZOrder > zOrderOfbottomNeighborPoint){
//						zOrderOfbottomNeighborPoint = previousFoundZOrder;
//					}
//				}
//			}
//			return (zOrderOfbottomNeighborPoint - 1) + constFix;
//		}
//		
//		return calculatedZ + constFix;
//    },

   getZ: function(forObject, gridPosition){
    	var constFix = 200;
    	
    	var gridSizeX = forObject.getGridSize().getX();
    	var gridSizeY = forObject.getGridSize().getY();
		var gridPositionX = gridPosition.getX();
		var gridPositionY = gridPosition.getY() + gridSizeY;
		var calculatedZ = (GAIsoMetricConfigurations.getGridSize().getX() * 2 + 1) - (gridPositionX + gridPositionY + 1);
		calculatedZ = calculatedZ *16;
		if (gridSizeX > gridSizeY){
			
			var XofObjectAtDiagonal =  gridPositionX+gridSizeX -1;
			var YofObjectAtDiagonal =  gridPositionY-gridSizeY -1;
			
			var bottomNeighborPoint = new Core.Vector(XofObjectAtDiagonal, YofObjectAtDiagonal);
			var bottomNeighbor = this.objectForGridPosition(bottomNeighborPoint);		
			
			if(typeof bottomNeighbor!='undefined' && bottomNeighbor != null){
				
				if(bottomNeighbor.getGridSize().getX()>bottomNeighbor.getGridSize().getY()){
									
					zOrderOfbottomNeighborPoint = bottomNeighbor.getObject().getDepth();
					var calculatedZofObject = (calculatedZ -1)+constFix;
					
						if(zOrderOfbottomNeighborPoint <= calculatedZofObject){
							return (zOrderOfbottomNeighborPoint -0.1);
					}
				return (calculatedZ -1)+constFix;			
			 	}				
			} 
            return (calculatedZ -1)+constFix;			
		}
		else if(gridSizeX<gridSizeY){
			
			var XofObjectAtDiagonal =  gridPositionX -1;
			var YofObjectAtDiagonal =  gridPositionY -1;	
					
			var bottomNeighborPoint = new Core.Vector(XofObjectAtDiagonal, YofObjectAtDiagonal);
			var bottomNeighbor = this.objectForGridPosition(bottomNeighborPoint);
	
			if(typeof bottomNeighbor!='undefined' && bottomNeighbor != null){
				
				if(bottomNeighbor.getGridSize().getX()<bottomNeighbor.getGridSize().getY()){
									
					zOrderOfbottomNeighborPoint = bottomNeighbor.getObject().getDepth();
					var calculatedZofObject = (calculatedZ +1)+constFix;
						if(zOrderOfbottomNeighborPoint <= calculatedZofObject){
							return (zOrderOfbottomNeighborPoint -0.1);
						}
				return (calculatedZ +1)+constFix;			
			  	}				
			} 					
			return (calculatedZ +1)+constFix;
		}
		return calculatedZ + constFix;
    },  
    
    addObject: function(theObject){
        if (this._actionType == ActionType.ActionMove){
        	if (this._highLightedObject != null){
        		if (this._isMovingAlreadyPlacedObject){
					this.cancelPlacingOfObject(this._highLightedObject);
        		}
        		else{
        			this.removeObject(this._highLightedObject);
        		}
        	}
        	else{
        		return;
        	}
        }
        if (theObject.getIsSelected()){
            var obj = theObject.getObject();
            this.addChild(obj);
            this.setSenderAsSelectedObject(theObject);
            obj.setDepth(this.getZ(theObject, this._tempPositionSelected));
        }
        else{
            var samplePoint = new Core.Vector(theObject.getGridLocation().getX(), theObject.getGridLocation().getY() + theObject.getGridSize().getY());
            this.addChild(theObject.getObject(), this.getZ(theObject, this._tempPositionSelected));
            theObject.getObject().setDepth(this.getZ(theObject, this._tempPositionSelected));
        }
    },
    
    removeObject: function(theObject){
    	if (theObject == null){
    		return;
    	}
												 
		if(theObject.getObject())
		{
			this.removeChild(theObject.getObject());
		}
    	return this.cleanGridForSpecificObject(theObject);
    },
    
    cancelPlacingOfObject: function(theObject){
    	if (!this._isMovingAlreadyPlacedObject){
    		return;
    	}
    	var previousPosition = theObject.getGridLocation();
    	if (this._collisionObject){
			this._collisionObject.unmarkAsRed();	
    	}
    	theObject.getObject().setPosition(this.convertGridPointToLayerPoint(previousPosition));
		theObject.getObject().setDepth(this.getZ(theObject, previousPosition));										 
    	theObject.setIsSelected(false);
		theObject.setOpacityToFull();
        this._highLightedObject = null;
        this._actionType = ActionType.ActionArrow;
        this._shouldMove = false;
        this._isMovingAlreadyPlacedObject = false;
        
        //GameController.getWidgetsLayer().allowMultiTools();
    },
    
    resetToPointer: function(){
		if (this._actionType == ActionType.ActionMove){
        	if (this._highLightedObject != null){
				if (this._isMovingAlreadyPlacedObject){
					this.cancelPlacingOfObject(this._highLightedObject);
        		}
        		else{
        			if (this._isRoadToolEnabled){
        				console.log('Logger: do nothing, leave the road there');
        			}
        			else{
	        			if (this._collisionObject){
	        				this._collisionObject.unmarkAsRed();
	        			}
	        			this.removeObject(this._highLightedObject);
	        			this._highLightedObject = null;
				        this._actionType = ActionType.ActionArrow;
				        this._shouldMove = false;
				        this._isMovingAlreadyPlacedObject = false;
        			}
        		}
        	}
    	}
    	
    	//GameController.getWidgetsLayer().allowMultiTools();
    },
    
    didTouchSelectedObject: function(gridLocationForTouch){
        if (!this._highLightedObject){
            return false;
        }
        var origin = new Core.Vector(this._tempPositionSelected.getX(),this._tempPositionSelected.getY());
        var size = new Core.Size(this._highLightedObject.getGridSize().getX(),this._highLightedObject.getGridSize().getY());
        var madeRect = new Core.Rect(origin,size);
        
        if (this.rectContainsPoint(madeRect, gridLocationForTouch)){
            return true;
        }
        else{
            return false;
        }
    },
    
    setHighligtedObjectAtPoint: function(point){
    	//console.log('Logger: HOBJECT GridX = ' + this._highLightedObject.getGridLocation().getX() + ' Y = ' + this._highLightedObject.getGridLocation().getY());
    	var locationInGrid = this.validateLocationForPointAndSize(point, this._highLightedObject.getGridSize());
    	this._highLightedObject.getObject().setPosition(this.convertGridPointToLayerPoint(locationInGrid));
    	this._tempPositionSelected = locationInGrid;
    	
    	this.checkCollisionWithGrid(this._highLightedObject);
    	this._highLightedObject.getObject().setDepth(this.getZ(this._highLightedObject, this._tempPositionSelected));
    	//console.log('Logger: HOBJECT GridX = ' + this._highLightedObject.getGridLocation().getX() + ' Y = ' + this._highLightedObject.getGridLocation().getY());
    },
    
    olTouchBegan: function(touch){
        if (this._actionType == ActionType.ActionMove){
            var point = this.conversionToLayer(touch);
            if (this.didTouchSelectedObject(point)){
                this._shouldMove = true;
                this._differenceBetweenTouch = new Core.Vector(this._tempPositionSelected.getX() - point.getX(), this._tempPositionSelected.getY()-point.getY());
            }
        }
    },
    
    olTouchMoved: function(touch,multiArray){
        this._count++;
		if(this._numTouches == 2)
		{
			this._myTouches = 2;
		}									 
        if (this._actionType == ActionType.ActionMove){
            if (multiArray == 2){
				this._myTouches = multiArray;								 
                this._isPinchingDisabled = false;
                this._isPanningDisabled = false;
                this._shouldMove = false;
                
                this._olDidMove = true;
                return;
            }
            
            if (this._shouldMove){
                var pointWithDifference = this.conversionToLayer(touch);
                pointWithDifference.setX(pointWithDifference.getX() + this._differenceBetweenTouch.getX());
                pointWithDifference.setY(pointWithDifference.getY() + this._differenceBetweenTouch.getY());
                
                this.setHighligtedObjectAtPoint(pointWithDifference);
                this._highLightedObject.getObject().setDepth(10000);
                this._isPanningDisabled = true;
            }
        }
        if(this._count > 5)
        {
            this._olDidMove = true;
        }
    },

    olTouchEnded: function(touch){
        var point = this.conversionToLayer(touch);
        
        this._isPinchingDisabled = false;
        this._isPanningDisabled = false;
        
        if (this._actionType == ActionType.ActionMove){
            if ((!this._olDidMove) && (!this.didTouchSelectedObject(point))){
	            this.setHighligtedObjectAtPoint(point);
            }
            else if ((!this._olDidMove) && (this.didTouchSelectedObject(point))){
                if(this._highLightedObject && (!this.checkCollisionWithGrid(this._highLightedObject))){
                    this._highLightedObject.tap();
				}
            }
        }
        else if (this._actionType == ActionType.ActionArrow){
			if (point.getX() < 0 || point.getY() < 0 ||  point.getX() >= GAIsoMetricConfigurations.getGridSize().getX() || point.getY() >= GAIsoMetricConfigurations.getGridSize().getY()){
	        	return;
	        }
	        if (!this._olDidMove){
	        	var theObject = this._gridObjects[point.getX()][point.getY()];
	        	if (theObject != null){
					theObject.tap();
	        	}
	        }
        }
        
        this._olDidMove = false;
        this._shouldMove = false;
    },
    
    setObjectToMovingMode: function(theObject){
    	this._highLightedObject = theObject;
		this._highLightedObject.setOpacityToLight();
		this.setIsMovingAlreadyPlacedObject(true);
		this._highLightedObject.setIsSelected(true);
		this.setSenderAsSelectedObject(this._highLightedObject);
    },
    
    finalizeObjectAtItsPlace: function(){
    	try{
	    	this.reserveGridForObject(this._highLightedObject);
	    	this._previouslyPlacedObjectPosition = this._highLightedObject.getGridLocation();
	       	this._highLightedObject.setOpacityToFull();
	        this._highLightedObject.begin();
	     	this._highLightedObject.updatePosition();
	        this._highLightedObject.getObject().setDepth(this.getZ(this._highLightedObject, this._tempPositionSelected));
	        this._highLightedObject = null;
	        this._actionType = ActionType.ActionArrow;
			this._shouldMove = false;
			this._isMovingAlreadyPlacedObject = false;
												 
			//console.log("Zulu:: Position X:::: "+ this._highLightedObject.getObjectPosition().getX() +"   Y::::"+this._highLightedObject.getObjectPosition().getX());
    	}
    	catch(_exception){
    		console.log('Logger: Exception occurred in Finalize of Object Layer: ' + _exception.toString());
    	}
    },
    
    setHighLightedObjectToNil: function(){
		this._highLightedObject = null;
		this._shouldMove = false;
		this._actionType = ActionType.ActionArrow;
    },
    
    objectForGridPosition: function(targetPoint){
        var x = targetPoint.getX();
        var y = targetPoint.getY();
        
        if (x<0 || x >= GAIsoMetricConfigurations.getGridSize().getX() || y<0 || y >= GAIsoMetricConfigurations.getGridSize().getY()){
            return null;
        }
        
        var uiObject = this._gridObjects[x][y];

        return uiObject;
    },
    
    cleanGridForSpecificObject: function(senderObject){
    	var wasObjectFoundOnGrid = false;
    	var endXPosition=  senderObject.getGridLocation().getX() +senderObject.getGridSize().getX();
    	var endYPosition=  senderObject.getGridLocation().getY() +senderObject.getGridSize().getY();
    	for (var i = (endXPosition-1); i>=senderObject.getGridLocation().getX(); i-- ){
    		for (var j = (endYPosition-1); j>=senderObject.getGridLocation().getY(); j--  ){
    			if (this._gridObjects[i][j] == senderObject){
    				wasObjectFoundOnGrid = true;
    				this._gridObjects[i][j] = null;
												 //console.log("Zulu: SENDER OBJECT HAS SET TO NULL NOW");
    			}
    		}
    	}
    	return wasObjectFoundOnGrid;
    },
    
    reserveGridForObject: function(senderObject){
        var locationX;
        var locationY;
        var sizeX;
        var sizeY;
        
        sizeX = senderObject.getGridSize().getX();
        sizeY = senderObject.getGridSize().getY();
        
        if (this.cleanGridForSpecificObject(senderObject)){
        	//console.log('Logger: previous reference removed');
        }
        locationX = this._tempPositionSelected.getX();
        locationY = this._tempPositionSelected.getY();
        
        var xLimit = locationX + sizeX;
        for(var i = locationX; i < xLimit; i++){
        	var yLimit = locationY + sizeY;
            for (var j = locationY; j < yLimit; j++){
                this._gridObjects[i][j] = senderObject;
            }
        }
        senderObject.setGridLocation(new Core.Vector(locationX,locationY));
	},
    
    
    validateLocationForPointAndSize: function(location,gridSizeOfObject){
        var tempPoint = location;
        if(location.getX() < 0)
            tempPoint.setX(0);
        if((tempPoint.getX() + gridSizeOfObject.getX()) >= (GAIsoMetricConfigurations.getGridSize().getX() - 1))
            tempPoint.setX(GAIsoMetricConfigurations.getGridSize().getX() - gridSizeOfObject.getX());
        if(tempPoint.getY() < 0)
            tempPoint.setY(0);
        if((tempPoint.getY() + gridSizeOfObject.getY()) >= (GAIsoMetricConfigurations.getGridSize().getY() - 1))
            tempPoint.setY(GAIsoMetricConfigurations.getGridSize().getY() - gridSizeOfObject.getY());

        tempPoint.setX(parseInt(tempPoint.getX() / 4));
        tempPoint.setY(parseInt(tempPoint.getY() / 4));

        tempPoint.setX(tempPoint.getX() * 4);
        tempPoint.setY(tempPoint.getY() * 4);

        return tempPoint;
    },
    
    setSenderAsSelectedObject: function(sender){
        sender.setIsSelected(true);
        this._highLightedObject = sender;
        this._tempPositionSelected = sender.getGridLocation();
        this._shouldMove = true;
        this._actionType = ActionType.ActionMove;
    },
    
    rectContainsPoint: function (rect,point){
        var rectX = rect.getOrigin().getX();
        var rectY = rect.getOrigin().getY();
        var rectWidth = rect.getSize().getWidth();
        var rectHeight =rect.getSize().getWidth(); 

        var pointX = point.getX();
        var pointY = point.getY();
        
        var temp;
        if ((pointX >= rectX && pointX <= (rectX + rectWidth)) && (pointY >= rectY && pointY <= (rectY + rectHeight))){
            temp = true;
        }
        else{
            temp = false;
        }

        return temp;
    },
    
    checkCollisionWithGrid: function(sender){
    	
    	var locationX;
        
        var sizeX = sender.getGridSize().getX();
        var sizeY = sender.getGridSize().getY();
        
        var doesCollide = false;
        var tempObject;
        var locationX = this._tempPositionSelected.getX();
        var locationY = this._tempPositionSelected.getY();

		if (this._collisionObject){
			this._collisionObject.unmarkAsRed();
		}

       
        for (var i = locationX; i < locationX + sizeX; i++){
            for (var j = locationY; j < locationY + sizeY; j++){
                tempObject = this._gridObjects[i][j];
                
                if (tempObject && (tempObject != this._highLightedObject)){   
						this._collisionObject = tempObject;
						doesCollide = true;
                }
            }
        }
            
        if (doesCollide){
            this._collisionObject.markAsRed();
            doesCollide = true;
			return doesCollide;
        }
        else{
            this._collisionObject = null;
        }
		
        return doesCollide;
    },
    
    destroy: function(){
        
    },
});